//package cn.bonoon.kernel.io.mapped;
//
//import java.io.File;
//
//import org.springframework.util.Assert;
//
//import cn.bonoon.kernel.io.AbstractFSResource;
//import cn.bonoon.kernel.io.BFile;
//import cn.bonoon.kernel.io.StorageInitizlier;
//import cn.bonoon.util.PathUtil;
//
///**
// * 一个catalog映射到多个存储的磁盘空间，并且使用“可用空间最大优先”的算法；
// * 
// * 注意：如果使用的是同个磁盘的不同目录，则只会使用第一个目录，所以这里定义的
// * 应该是不同的硬盘空间
// * @author jackson
// *
// */
//public class FSStreamRandom extends AbstractFSResource{
//	
//	/** 实际的用于保存文件的目录地址 */
//	private final String[] paths;
//	
//	/** 记录下磁盘的可用空间，优先选择可用空间大的磁盘进行存储 */
//	private final long[]  freeSpaces;
//	
//	public FSStreamRandom(String mappedPath, String... paths){
//		super(mappedPath);
//		Assert.noNullElements(paths, "保存的目录不能为空！");
//		this.paths = paths;
//		this.freeSpaces = new long[paths.length];
//	}
//	
//	@Override
//	public void init(StorageInitizlier initizlier) {
//		super.init(initizlier);
//		
//		int i = 0;
//		for(String root : listRoots()){
//			try{
//				freeSpaces[i] = new File(root).getFreeSpace();
//			}catch(Exception ex){
//				//无法访问磁盘：root.getPath();
//			}
//			
//			i++;
//		}
//	}
//	
//	@Override
//	public String[] listRoots() {
////		File[] files = new File[paths.length];
////		for(int i = 0; i < paths.length; i ++){
////			files[i] = new File(paths[i]);
////		}
//		return paths;
//	}
//
//	/** 解析出相对路径所存储在系统的具体的位置 */
//	public String[] resolveRealPaths(BFile file){
//		String rpath = file.getPath().substring(pathOffset);
//		String[] newPaths = new String[paths.length];
//		for(int i = 0; i < paths.length; i++){
//			newPaths[i] = PathUtil.path(paths[i], rpath);
//		}
//		return newPaths;
//	}
////	
////	protected class RandomStorageEvent extends InternalStorageEvent{
////		protected File folder;
////		/** 用于表示哪些存储磁盘已经不可用了 */
////		private boolean[] disableds;
////		private int indexOfCandidatePath = -1;
////		private long freeSpace;
////		
////		protected RandomStorageEvent(StorageFile saveFileInfo) throws Exception {
////			super(saveFileInfo);
////			disableds = new boolean[candidatePaths.length];
////		}
////		
////		@Override
////		protected File candidateStorageFolder(StorageFile saveFileInfo, long size) throws Exception {
////			
////			/*
////			 * 优先使用记录中最大的空间的磁盘；
////			 * 这里并不是实际磁盘的最大的空间，而是在启动的时候，已经记录的最大的空间，
////			 * 如果其它服务器已经多次有写入的操作，则可能这次取到的可用的空间并不是最
////			 * 大的，在保存之后，将会重新更新记录中的可用空间的大小。
////			 */
////			while(null == folder || size > folder.getFreeSpace()){
////				folder = null;
////				for(int i = 0; i < candidatePaths.length; i++){
////					if(disableds[i]) continue;
////					
////					if(size > freeSpaces[i]){
////						/*
////						 * 如果某个磁盘在服务器启动时不可用，则这里记录的是0，这样的话在对文件进行存储的时候，
////						 * 则认为这个磁盘的可用空间为0，即无法存储文件。
////						 * 
////						 * 是否需要在某个地方重新检查磁盘的可用空间？
////						 */
////						disableds[i] = true;
////						continue;
////					}
////					
////					if(freeSpaces[i] > freeSpace){
////						//找出记录表中的最大的可用空间
////						freeSpace = freeSpaces[i];
////						indexOfCandidatePath = i;
////					}
////				}
////				
////				if(indexOfCandidatePath >= 0){
////					File candidateFolder = new File(candidatePaths[indexOfCandidatePath]);
////					freeSpaces[indexOfCandidatePath] = candidateFolder.getFreeSpace();
////					if(freeSpaces[indexOfCandidatePath] > size){
////						folder = candidateFolder;
////						
////						return folder;
////					}
////					
////					/*
////					 * 如果记录表中最大的可用空间足够存储某个文件，但在具体调用这个目录的时候，
////					 * 检查到对应的磁盘的可用空间不足的情况，如：由其它的服务器进行写入，致其可
////					 * 用空间不足的情况，则在本服务器上记录为不可用，在上面已经更新了该磁盘可用
////					 * 空间的信息了。
////					 * 
////					 * 继续从其它磁盘上解析，直到所有的空间都不可用。
////					 */
////					disableds[indexOfCandidatePath] = true;
////				}
////			}
////			
////			if(null == folder){
////				throw new DiskNospaceExcpetion("没有找到足够的空间来存储[" + saveFileInfo + "]！");
////			}else if(size > folder.getFreeSpace()){
////				throw new DiskNospaceExcpetion(
////						"目录【" + folder.getPath() + 
////						"】空间[可用" + folder.getFreeSpace() + 
////						" / 需要" + size + "byte]不足！");
////			}
////			
////			/*
////			 * 这里是第二次进来，并且空间足够的情况，优先使用上一次存储文件时所使用的目录
////			 */
////			return folder;
////		}
////	}
////
////	@Override
////	protected InternalStorageEvent generateEvent(StorageFile file) throws Exception {
////		return new RandomStorageEvent(file);
////	}
//}
